package service

import (
	"errors"
	"gdmin/db"
	"gdmin/global"
	"gdmin/model"
	"gdmin/servlet"
	"gorm.io/gorm"
	"strconv"
)

type DeptService struct{}

func (deptService *DeptService) List(pid string) []servlet.DeptResp {
	var d []servlet.DeptResp

	query := global.DB.Model(&d)
	if pid != "" {
		query.Where("pid = ?", pid)

	}
	query.Find(&d)
	return d
}

func (deptService *DeptService) ById(id string) *servlet.DeptResp {
	var res servlet.DeptResp

	global.DB.First(&res, id).Find(&res)
	if res.Id > 0 {

		if res.Pid > 0 {
			res.ParentDeptName = deptService.findName(strconv.Itoa(res.Pid))
		}
		return &res
	}
	return nil
}

func (deptService *DeptService) findName(id string) string {
	var res servlet.DeptResp
	err := global.DB.First(&res, id).Find(&res).Error
	if err != nil {
		return res.Name
	}
	return ""

}

func (deptService *DeptService) QueryDept(req *servlet.QueryDeptReq) *servlet.Pagination {
	var d []*servlet.DeptResp

	query := global.DB.Model(&d)
	if req.Name != "" {
		query.Where("name like ? ", "%"+req.Name+"%")
	}

	if req.Pid > 0 {
		query.Where("pid = ? ", req.Pid)

	}

	page := db.CommonPage(&req.Pagination, &d, query)
	for _, v := range d {
		// 处理v
		id := deptService.ById(strconv.Itoa(v.Pid))
		if id != nil {
			v.ParentDeptName = id.Name
		}
	}
	return page
}

func (deptService *DeptService) UpdateDept(req *servlet.UpdateDeptReq) (*model.Dept, error) {
	if req.Id <= 0 {
		return nil, errors.New("部门id必填")
	}
	if req.Name == "" {
		return nil, errors.New("部门名称必填")

	}

	var old model.Dept
	err := global.DB.First(&old, req.Id).Error
	if err != nil {
		return nil, err
	} else {

		err = checkDeptNameRequire(req.Name, req.Id)
		if err != nil {
			return nil, err
		}
		old.Name = req.Name

		old.Pid = req.Pid
		err = global.DB.Transaction(func(tx *gorm.DB) error {
			return tx.Save(&old).Error
		})
		if err != nil {
			return nil, err
		} else {

			return &old, nil

		}

	}

}

func (deptService *DeptService) CreateDept(s *servlet.CreateDeptReq) (*model.Dept, error) {
	if s.Name == "" {
		return nil, errors.New("部门名称必填")
	}
	err := checkDeptNameRequire(s.Name, -1)

	if err != nil {
		return nil, err
	} else {
		var dept model.Dept
		dept.Name = s.Name
		dept.Pid = s.Pid

		err = global.DB.Transaction(func(tx *gorm.DB) error {
			return tx.Create(&dept).Error
		})
		if err != nil {
			return nil, err
		} else {
			return &dept, nil
		}
	}
}

func (deptService *DeptService) Tree(param string) ([]model.NodeWithChildren, error) {
	if param != "" {

		atoi, err := strconv.Atoi(param)
		if err != nil {
			return nil, err
		}

		return deptService.deptTree(atoi), nil
	} else {
		return deptService.deptTree(-1), nil
	}
}

func (deptService *DeptService) deptTree(pid int) []model.NodeWithChildren {

	var mts []model.Dept

	if pid > 0 {
		global.DB.Where("pid =?", pid).Find(&mts)
	} else {
		err := global.DB.Model(&model.Dept{}).Find(&mts).Error
		if err != nil {
			panic(err)
		}
	}

	dept := model.Dept{}
	tree := dept.MakeTree(mts)

	return tree
}

func (deptService *DeptService) DeleteById(param string) {
	global.DB.Where("id =?", param).Delete(&model.Dept{})
}

func (deptService *DeptService) HandlerUserInfo(s *servlet.UserResp) {
	var d []model.DeptBindUser
	global.DB.Model(&model.DeptBindUser{}).Where("user_id =?", s.Id).Find(&d)

	var deptIds []int
	for _, item := range d {
		if item.IsMain {
			s.MainDeptId = item.DeptId
		}
		deptIds = append(deptIds, item.DeptId)
	}
}

func checkDeptNameRequire(name string, id int) error {
	dept := model.Dept{}
	err := global.DB.Where("name =?", name).First(&dept).Error

	if err == nil {
		if dept.Id == 0 {
			return nil
		}
		if dept.Id != id {

			return errors.New("部门名称已存在")
		}
		return nil
	} else {

		if errors.Is(err, gorm.ErrRecordNotFound) {
			return nil
		}
		return err
	}
}
